using System.Collections.Generic;
using Utils;
using Game.Networking.Server;

namespace Game.UI {
	public class ServerComputingUnitUserDataProvider : IComputingUnitUserDataProvider {
		public uint GetAttachedUnitId() {
			return ServerDebugController.Instance?.WatchedUnitId ?? 0;
		}

		public ServerScriptController SC => ServerScriptController.Instance;

		public ServerDebugController DC => ServerDebugController.Instance;

		public EventBus OnCodeFileListUpdated => DC.DebugUnitWatcher.FileListChangedBus;

		public EventBus<string> OnCodeFileUpdated => DC.DebugUnitWatcher.CodeFileUpdatedBus;

		public EventBus OnUnitStateChanged => DC.DebugUnitWatcher.UnitStateChangedBus;

		public EventBus OnTerminalCommandReceived => DC.DebugUnitWatcher.TerminalCommandBus;

		public EventBus<uint> OnAttachedEntityIdChanged => DC.DebugUnitWatcher.AttachedEntityChangedBus;

		public void CreateNewCodeFile(string fileName, string contents) {
			var unit = SC.GetUnitById(GetAttachedUnitId());
			if ( unit == null ) {
				return;
			}

			unit.AddOrReplaceSourceCode(fileName, contents);
		}

		public List<string> GetCodeFiles() {
			var unit = SC?.GetUnitById(GetAttachedUnitId());
			if ( unit == null ) {
				return new List<string>();
			}

			return unit.GetSourceCodeFileNames();
		}

		public string GetFileContents(string fileName) {
			var unit = SC.GetUnitById(GetAttachedUnitId());
			if ( unit == null ) {
				return null;
			}

			return unit.GetSourceCodeFile(fileName);
		}

		public bool IsCodeFileDownloaded(string fileName) {
			var unit = SC?.GetUnitById(GetAttachedUnitId());
			if ( unit == null ) {
				return false;
			}

			return unit.HasSourceCodeFile(fileName);
		}

		public void SaveCodeFile(string fileName, string contents) {
			CreateNewCodeFile(fileName, contents);
		}

		public void SendRecompileRequest() {
			SC?.RequestRecompile(GetAttachedUnitId());
		}

		public void TryDownloadCodeFile(string fileName) {
			return;
		}

		public ComputingUnitState GetCurrentUnitState() {
			var unit = SC?.GetUnitById(GetAttachedUnitId());
			if ( unit == null ) {
				return ComputingUnitState.Uninitialized;
			}

			return unit.State;
		}

		public void SendTerminalMessage(string message) {
			var unit = SC?.GetUnitById(GetAttachedUnitId());
			if ( unit == null ) {
				return;
			}

			unit.ProcessConsoleMessage(message);
		}

		public List<string> GetTerminalMessages() {
			var unit = SC.GetUnitById(GetAttachedUnitId());
			if ( unit == null ) {
				return null;
			}

			return unit.TextTerminal.Messages;
		}

		public uint GetAttachedEntityId() {
			var unit = SC.GetUnitById(GetAttachedUnitId());
			if ( unit == null ) {
				return 0;
			}

			return unit.Data.AttachedEntity;
		}

		public void TryRemoveFile(string fileName) {
			var unit = SC.GetUnitById(GetAttachedUnitId());
			if ( unit == null ) {
				return;
			}

			unit.RemoveSourceCode(fileName);
		}

		public ShipCore GetAttachedEntity() {
			var id = GetAttachedEntityId();
			if ( id == 0 ) {
				return null;
			}

			var e = ServerEntityController.Instance.GetEntityById(id);
			if ( e == null ) {
				return null;
			}

			var ship = (ShipCore)e;
			if ( ship == null ) {
				return null;
			}

			return ship;
		}

		public void SaveCodeFileLocally(string fileName, string contents) {
			SaveCodeFile(fileName,
				contents); //На сервере, ввиду отсутствия временного хранилища, сохраняем сразу в постоянное
		}

		public void UploadFiles() {
			throw new System.NotImplementedException();
		}

		public void DownloadFiles() {
			throw new System.NotImplementedException();
		}
	}
}